(require (file "table-helper.scm"))
(load "interaction-utils.scm")
(load "make-place.scm")


(define (parse-file filename)
  (let ((file-stream (open-input-file filename 'text))
        (temp-list '()))
    (begin (set! temp-list (load-worlds '() file-stream))
           (close-input-port file-stream)
           temp-list)))
    

(define (load-worlds worlds file-stream)
  (let ((world-list worlds))
  (begin (read-until-text file-stream)
         (cond ((eof-object? (peek-char file-stream))
                world-list)
               ((equal? ";" (peek-string 1 0 file-stream))
                (load-worlds (cons (name-part file-stream) world-list) file-stream))
               ((equal? "%" (peek-string 1 0 file-stream))
                (begin (read-string 1 file-stream)
                       (load-worlds world-list file-stream)))
               (else world-list)))))
      ;(raise-syntax-error 'parse "Expected a new world definition")

;    (begin (read-until-text file-stream)
;          (if (equal? ";" (read-string 1 file-stream))
;             (name-part file-stream)
;            "Something is wrong"))))

; the name must be written like
; " ; name = Axlings place in heaven % " in the file
(define (name-part file-stream)
  (begin (read-until-text file-stream)
         (if (equal? ";" (read-string 1 file-stream))
             (begin (read-until-text file-stream)
                    (if (equal? (read-string 4 file-stream) "name")
                        (begin (read-until-text file-stream)
                               (if (equal? "=" (read-string 1 file-stream))
                                   (begin (read-until-text file-stream)
                                          (description-part (save-string-until-char "%" 0 file-stream) file-stream))
                                   (raise-syntax-error 'parse "Expected = symbol in namef definition")))
                        (raise-syntax-error 'parse "Expected name string in name definition")))
             (raise-syntax-error 'parse "Expected ; symbol in name-definition")))
  )

; Description about the place must be written like
; " ; description = This room is fucking awesome! % "in the file
(define (description-part name file-stream)
  (begin (read-until-text file-stream)
         (if (equal? "%" (read-string 1 file-stream))
             (begin (read-until-text file-stream)
                    (if (equal? ";" (read-string 1 file-stream))
                        (begin (read-until-text file-stream)
                               (if (equal? "description" (read-string 11 file-stream))
                                   (begin (read-until-text file-stream)
                                          (if (equal? "=" (read-string 1 file-stream))
                                              (begin (read-until-text file-stream)
                                                     (npc-part name (save-string-until-char "%" 0 file-stream) file-stream))
                                              (raise-syntax-error 'parse "Expected = symbol in desc def")))
                                   (raise-syntax-error 'parse "Expected description string in desc def")))
                        (raise-syntax-error 'parse "Expected ; symbol in desc def")))
             (raise-syntax-error 'parse "Expected % symbol in name def")))
  )

;NPC-list 
; ( 

(define (npc-part name description file-stream)
  (begin (read-until-text file-stream)
         (if (equal? "%" (read-string 1 file-stream))
             (begin (read-until-text file-stream)
                    (if (equal? ";" (read-string 1 file-stream))
                        (begin (read-until-text file-stream)
                               (if (equal? "npc" (read-string 3 file-stream))
                                   (begin (read-until-text file-stream)
                                          (if (equal? "=" (read-string 1 file-stream))
                                              (begin (read-until-text file-stream)
                                                     (item-part name description (save-list '() file-stream) file-stream))
                                              (raise-syntax-error 'parse "Expected = symbol in npc def")))
                                   (raise-syntax-error 'parse "Expected npc string in npc def")))
                       (raise-syntax-error 'parse "Expected ; symbol in npc def")))
            (raise-syntax-error 'parse "Expected % symbol in desc def")))
  )

; npcs must be written like 
; " ; npc = dude, man, erik, seb, chrille,% " in the file its important
; to finish with a comma before the percent sign
(define (save-list some-list file-stream)
  (let ((chr (peek-string 1 0 file-stream)))
    (begin
      (read-until-text file-stream)
      (if (equal? chr ",")
          (begin (read-string 1 file-stream)
                 (read-until-text file-stream)
                 (if (equal? "%" (peek-string 1 0 file-stream))
                     some-list
                     (begin (save-list (append some-list (list (save-string-until-char "," 0 file-stream))) file-stream)
                            )
                    ))
          (raise-syntax-error 'parse "Expected a , symbol")))
    )
  )


(define (item-part name description npc-list file-stream)
  (begin (read-until-text file-stream)
         (if (equal? "%" (read-string 1 file-stream))
             (begin (read-until-text file-stream)
             (if (equal? ";" (read-string 1 file-stream))
                         (begin (read-until-text file-stream)
                                (if (equal? "items" (read-string 5 file-stream))
                                    (begin (read-until-text file-stream)
                                           (if (equal? "=" (read-string 1 file-stream))
                                               (begin (read-until-text file-stream)
                                                      (direction-part name description npc-list (save-list '() file-stream) file-stream))
                                               (raise-syntax-error 'parse "Expected = symbol in items def")))
                                    (raise-syntax-error 'parse "Expected items string in items def")))
                        (raise-syntax-error 'parse "Expected ; symbol in items def")))
             (raise-syntax-error 'parse "Expected % symbol in npc def"))
  ))
  

(define (direction-part name description npc-list item-list file-stream)
  (begin (read-until-text file-stream)
         (if (equal? "%" (read-string 1 file-stream))
             (begin (read-until-text file-stream)
                    (if (equal? ";" (read-string 1 file-stream))
                        (begin (read-until-text file-stream)
                               (if (equal? "directions" (read-string 10 file-stream))
                                   (begin (read-until-text file-stream)
                                          (if (equal? "=" (read-string 1 file-stream))
                                              (begin (read-until-text file-stream)
                                                     ; Here we need to save the readin as an object
                                                     (list (make-place (string->symbol name) description) 
                                                                          npc-list item-list (save-list '() file-stream)))
                                              (raise-syntax-error 'parse "Expected = symbol in directions def")))
                                   (raise-syntax-error 'parse "Expected directions string in directions def")))
                        (raise-syntax-error 'parse "Expected ; symbol in directions def")))
             (raise-syntax-error 'parse "Expected % symbol in items def"))
         ))
   

(define (read-until-char chr file-stream)
  (begin (read-until-text file-stream)
         (if (equal? chr (peek-string 1 0 file-stream) )
             (read-string 1 file-stream)
             (begin (read-string 1 file-stream)
                    (read-until-char chr file-stream)))))

(define (save-string-until-char chr skip file-stream)
  (if (equal? chr (peek-string 1 skip file-stream))
      (read-string skip file-stream)
      (save-string-until-char chr (+ 1 skip) file-stream)))

(define (read-until-text file-stream)
  (cond ((equal? (peek-string 1 0 file-stream) " ")
         (begin (read-string 1 file-stream)
                (read-until-text file-stream)))
        ((eof-object? (peek-char file-stream))
         '())
      ))